/*
 * SamplePlugin.Echo2
 * Andy Tidball
 * 
 * Project: Black Lightning Sample Plugin
 * Copyright: GNU General Public License
 */

using System;
using System.Text;
using System.Text.RegularExpressions;
using BlackLightning.PluginLib;
using BlackLightning.PluginLib.Modules;

// In this file I've implemented EchoModule again, only this time it derives from Module instead of IModule.
// Module provides a whole bunch of helper functions that make our code here a lot nicer and easier to with.
// This file is basically copy/pasted from the other EchoModule and modified to use the helper functions.
// I've removed all the comments from within functions EXCEPT where the helper functions are used, so the changes are easy to spot.

// I commented this out so that you don't end up using both echo modules at the same time
//[assembly: BLModule(typeof(SamplePlugin.EchoModule2))]

namespace SamplePlugin {
	/// <summary>
	/// A sample module which implements a simple @echo command.
	/// </summary>
	[ModuleName("Echo2")]
	public class EchoModule2 : Module {
		// constants
		private const string HelpText  = @"This module implements the @echo command.";
		private const string EchoUsage = @"@echo [string]
  string: The string to echo to the front end.";

		// we don't need the SendMessage and SendPacket events here, because our base class implements them already
		
		// note that our base class also implements GetProperty, HandleMessage, and HandlePacket
		// however, since it cannot provide the actual code for them (that's our job), it labels them "abstract"
		// that means a lot of things, but for our purposes it means we need to label our functions with the "override" keyword

		/// <summary>
		/// Gets a property of the module.
		/// </summary>
		/// <param name="Property">The property of the module that Black Lightning is requesting.</param>
		/// <returns>The value of the requested property, or null if this module doesn't use that property.</returns>
		public override object GetProperty(ModuleProperty Property) {
			switch (Property) {
				case ModuleProperty.HelpText: return HelpText;
				default:                      return null;
			}
		}

		/// <summary>
		/// Called by Black Lightning whenever it has a private message for us.
		/// </summary>
		/// <param name="Message">The private message that Black Lightning is sending to us.</param>
		public override void HandleMessage(Message Message) {
			if (Message is LoadedMessage) {
				HandleMessage_Loaded(Message as LoadedMessage);
			} else if (Message is UnloadedMessage) {
				HandleMessage_Unloaded(Message as UnloadedMessage);
			}
		}

		/// <summary>
		/// Handles all LoadedMessages sent to us.
		/// </summary>
		/// <param name="Message">The LoadedMessage sent to us by Black Lightning.</param>
		private void HandleMessage_Loaded(LoadedMessage Message) {
			// here I can replace a whole bunch of object creation with a simple function call
			// before:
			//SendMessage(this, new SendMessageEventArgs(new RegisterPacketMessage(new CommandPacketFilter(Program.FrontEnd, Program.BlackLightning, "@echo"))));
			// after:
			base.RegisterPacket(new CommandPacketFilter(Program.FrontEnd, Program.BlackLightning, "@echo"));

			// note that there are other helper functions for dealing with options as well
			// see the SamplePlugin class for more information about options
		}

		/// <summary>
		/// Handles all UnloadedMessages sent to us.
		/// </summary>
		/// <param name="Message">The UnloadedMessage sent to us by Black Lightning.</param>
		private void HandleMessage_Unloaded(UnloadedMessage Message) {
		}

		/// <summary>
		/// Called by Black Lightning whenever it has a packet for us to process.
		/// </summary>
		/// <param name="Packet">The packet that we should handle.</param>
		public override void HandlePacket(ref BLPacket Packet) {
			CommandPacket P = Packet as CommandPacket;

			if (P.Arguments.Length == 0) {
				// here we can also replace a bunch of object creation with a simple function call
				// before:
				//SendPacket(this, new SendPacketEventArgs(new RawBLPacket(Program.BlackLightning, Program.FrontEnd, EchoUsage)));
				// after:
				base.SendToFrontEnd(EchoUsage);
				return;
			}

			string Output = string.Join(" ", P.Arguments);

			// here again we can save some annoying object creation with the same function call
			// before:
			//RawBLPacket OutputPacket = new RawBLPacket(Program.BlackLightning, Program.FrontEnd, Output);
			//SendPacket(this, new SendPacketEventArgs(OutputPacket));
			// after:
			base.SendToFrontEnd(Output);

			P.Suppress();
		}
	}
}
